import cv2
import numpy as np
import pyautogui
import random
import time
from PIL import ImageGrab
import game_automator_module

# --------- 参数配置 ---------
SCREEN_REGION = (0, 0, 1920, 1080)
MIN_CONTOUR_AREA = 50
TEMPLATE_CONFIDENCE = 0.75

# --------- 通用截图 ---------
def screenshot_cv2():
    img = ImageGrab.grab()
    return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

def capture_screen():
    screen = ImageGrab.grab(bbox=SCREEN_REGION)
    return cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2BGR)

def get_template_positions(template_path, threshold=0.75):
    """返回所有匹配模板的区域中心点（用于排除干扰区域）"""
    screenshot = screenshot_cv2()
    template = cv2.imread(template_path)
    if template is None:
        print(f"错误：无法加载模板：{template_path}")
        return []

    res = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
    loc = np.where(res >= threshold)
    h, w, _ = template.shape

    centers = []
    for pt in zip(*loc[::-1]):
        cx = pt[0] + w // 2
        cy = pt[1] + h // 2
        centers.append(((pt[0], pt[1]), (pt[0] + w, pt[1] + h)))  # 返回左上和右下角坐标
    return centers

def point_in_rect(x, y, rect):
    (x1, y1), (x2, y2) = rect
    return x1 <= x <= x2 and y1 <= y <= y2

# --------- 模板点击函数 ---------
def find_and_click(template_path, confidence=TEMPLATE_CONFIDENCE):
    try:
        screenshot = screenshot_cv2()
        template = cv2.imread(template_path)
        if template is None:
            print(f"错误：无法加载模板：{template_path}")
            return False

        screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
        template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
        res = cv2.matchTemplate(screenshot_gray, template_gray, cv2.TM_CCOEFF_NORMED)
        _, max_val, _, max_loc = cv2.minMaxLoc(res)

        if max_val >= confidence:
            h, w = template_gray.shape
            center_x = max_loc[0] + w // 2
            center_y = max_loc[1] + h // 2

            print(f"找到按钮 [{template_path}]，置信度：{max_val:.2f}，坐标：({center_x}, {center_y})")
            try:
                pyautogui.moveTo(center_x, center_y, duration=0.2)
                pyautogui.click()
            except pyautogui.FailSafeException:
                print("触发 FailSafe，中断点击")
                return False
            print("已点击按钮！")
            return True
        else:
            print(f"未找到按钮 [{template_path}] 或置信度过低 ({max_val:.2f})")
            return False
    except Exception as e:
        print(f"发生错误：{e}")
        return False

# --------- 小人识别相关 ---------
def detect_moving_objects(prev_frame, current_frame):
    gray1 = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
    frame_diff = cv2.absdiff(gray1, gray2)
    _, thresh = cv2.threshold(frame_diff, 25, 255, cv2.THRESH_BINARY)
    dilated = cv2.dilate(thresh, None, iterations=2)
    contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    return contours

def select_random_target(contours):
    # 检测 nav 区域
    nav_regions = get_template_positions("templates/nav.png", threshold=0.7)

    valid_targets = []
    for cnt in contours:
        if cv2.contourArea(cnt) > MIN_CONTOUR_AREA:
            M = cv2.moments(cnt)
            if M["m00"] != 0:
                cx = int(M["m10"] / M["m00"])
                cy = int(M["m01"] / M["m00"])
                screen_x = cx + SCREEN_REGION[0]
                screen_y = cy + SCREEN_REGION[1]

                # 排除 nav 动画区域
                in_nav = any(point_in_rect(screen_x, screen_y, region) for region in nav_regions)
                if not in_nav:
                    valid_targets.append((screen_x, screen_y))

    if valid_targets:
        return random.choice(valid_targets)
    return None

def is_scene_changed(reference_frame, current_frame, threshold=0.1):
    gray1 = cv2.cvtColor(reference_frame, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
    diff = cv2.absdiff(gray1, gray2)
    _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)
    changed_pixels = np.count_nonzero(thresh)
    total_pixels = thresh.size
    change_ratio = changed_pixels / total_pixels
    print(f"画面变化比率: {change_ratio:.3f}")
    return change_ratio > threshold

# --------- 自动点击运动小人 ---------
def auto_click_moving_characters():
    print("=== 开始自动点击运动小人 ===")
    prev_frame = capture_screen()
    reference_frame = prev_frame.copy()
    time.sleep(0.5)

    while True:
        current_frame = capture_screen()
        contours = detect_moving_objects(prev_frame, current_frame)
        target_pos = select_random_target(contours)

        if target_pos:
            try:
                pyautogui.moveTo(target_pos[0], target_pos[1], duration=0.2)
                pyautogui.click()
            except pyautogui.FailSafeException:
                print("FailSafe 中断点击流程")
                break

            print(f"点击小人，位置：{target_pos}")
            time.sleep(1.2)
            after_click_frame = capture_screen()

            if is_scene_changed(reference_frame, after_click_frame):
                print("✅ 场景已变化，尝试点击小游戏按钮")
                time.sleep(2)
                if find_and_click("templates/mini_game.png"):
                    print("小游戏按钮已点击，等待加载")
                    time.sleep(1.0)
                    if find_and_click("templates/mini_game_start.png"):
                        print("✅ 已点击开始游戏")
                    else:
                        print("❌ 未找到开始游戏按钮")
                else:
                    print("❌ 未找到小游戏按钮")
                break
            else:
                print("场景未变化，继续寻找小人")

            prev_frame = capture_screen()
        else:
            prev_frame = current_frame

        time.sleep(0.1)

# --------- 封装主流程的函数 ---------
def start_full_automation_process():
    """
    启动完整的自动化流程：优远界 -> 大厅 -> 小人 -> 小游戏 -> 开始游戏 -> 进入小游戏自动化。
    """
    print("启动流程：优远界 → 大厅 → 小人 → 小游戏 → 开始游戏")

    # 假设 find_and_click 等函数在本文件中或已被导入
    find_and_click("templates/yyj_icon.png") # 如果需要点击优远界图标
    time.sleep(1)
    find_and_click("templates/hall.png")    # 如果需要点击大厅
    time.sleep(2)
    find_and_click("templates/chunjin.png")
    time.sleep(1)
    auto_click_moving_characters()         # 如果需要自动点击小人进入小游戏

    # 假设上面的步骤已经完成，或者您只希望从某个特定点开始
    # 根据您的描述，似乎auto_click_moving_characters()会尝试进入小游戏并点击开始
    # 所以完整的流程可能只需要调用 auto_click_moving_characters() 然后让它触发后续的逻辑
    # 或者，您可以根据实际需求调整这里的调用顺序

    # 当前逻辑是：点击小人 -> 进小游戏 -> 点击开始 -> 调用 game_automator_module 中的自动化
    # 这里假设 auto_click_moving_characters 成功进入了小游戏并点击了开始
    # 然后调用 game_automator_module 中的自动化函数
    print("假设已通过 auto_click_moving_characters 进入小游戏并点击开始...")
    # 调用 game_automator_module 模块中的自动化函数
    game_automator_module.run_game_automation()

# --------- 文件直接运行时执行的代码 ---------
if __name__ == "__main__":
    # 当直接运行此文件时，调用封装好的主流程函数
    start_full_automation_process()